#include "SrVideoThread.h"

#include "myplayer/SrVideoWidget.h"

SrVideoThread::SrVideoThread()
    :m_video_decode(NULL)
    ,m_video_show(NULL)
    ,_isExit(false)
{

}

SrVideoThread::~SrVideoThread()
{
    _isExit = true;
}


bool SrVideoThread::Open(AVCodecParameters *codecpar, ISrVideoShow *show, int width, int height)
{
    if (!codecpar)
    {
        return false;
    }
    _syncPts = 0;
    videoPts = 0;

    // 初始化显示窗口
    m_video_show = show;
    if (m_video_show)
    {
        m_video_show->Init(width, height);
    }

    // 打开解码器
    if (!m_video_decode)
    {
        m_video_decode = new SrDecode();
    }

    bool re = true;
    if (!m_video_decode->Open(codecpar, true))
    {
        re = false;
        qDebug("video XDecode open failed!\n");
    }

    qDebug("SrVideoThread::Open : %d\n",re) ;
    return re;
}

// 清理资源, 停止线程
void SrVideoThread::Close()
{
    // 等待线程退出
    _isExit = true;
    QThread::wait();

    Clear();

    m_video_decode->Close();

    delete m_video_decode;
    m_video_decode = NULL;

}

void SrVideoThread::Clear()
{
    _mux.lock();
    while (!_packs.empty())
    {
        AVPacket *pkt = _packs.front();
        av_packet_free(&pkt);
        _packs.pop_front();
    }
    _mux.unlock();
}

void SrVideoThread::Push(AVPacket *pkt)
{
    if (!pkt) return;

    // 阻塞
    while (!_isExit)
    {
        _mux.lock();
        if (_packs.size() < _maxList)
        {
            _packs.push_back(pkt);
            _mux.unlock();
            break;
        }
        _mux.unlock();
        msleep(1);
    }
}

void SrVideoThread::run()
{
    while (!_isExit)
    {
        _mux.lock();

        // 没有数据
        if (_packs.empty())
        {
            _mux.unlock();
            msleep(1);
            continue;
        }

        if(_syncPts < videoPts)
        {
            //需要放慢播放
            _mux.unlock();
            msleep(1);
            continue;
        }


        AVPacket *pkt = _packs.front();
        _packs.pop_front();

        _mux.unlock();

        bool re = m_video_decode->Send(pkt);
        if (!re)
        {
            //_mux.unlock();
            msleep(1);
            continue;
        }
        // 一次Send可能有多次recv
        while (!_isExit)
        {
            AVFrame *frame = m_video_decode->Recv();
            if (!frame)
            {
                break;
            }
            videoPts = frame->pts;
            // 显示视频
            if (m_video_show)
            {
                m_video_show->Repaint(frame);
            }
        }

    }
}

